#include "pch.h"
#include <io.h>
#include "../Base/Base.h"
#include "SyncDataCache.h"

SyncDataCache::SyncDataCache()
{
}


SyncDataCache::~SyncDataCache()
{
}

void SyncDataCache::load()
{
    struct _finddata_t fileinfo;

    auto handle = _findfirst("./temp/*.sync", &fileinfo);
    if (handle == -1)
        return;

    do
    {
        LOG(INFO) << "Read file " << fileinfo.name;

        std::string full_name = "./temp/";
        full_name += fileinfo.name;

        TableDatas table_datas;
        readFile(full_name.c_str(), table_datas);

        std::string table_name = std::string(fileinfo.name);
        StringReplace(table_name, ".sync", "");

        tables_datas_[table_name] = table_datas;
    } while (!_findnext(handle, &fileinfo));

    _findclose(handle);
}

void SyncDataCache::setSuccessed(const std::string &table, const Data & data)
{
	CriticalSectionUtil cs_util = CriticalSectionUtil(cs_);

    auto iter = std::find(tables_datas_[table].datas_.begin(), tables_datas_[table].datas_.end(), data);

    if (iter == tables_datas_[table].datas_.end())
    {
        return;
    }

    iter->is_successed_ = true;

    saveFile(table.c_str(), tables_datas_[table]);
}

void SyncDataCache::addData(const enclave::SyncTablesDatas &sync_tables_datas)
{
    for (int i = 0; i < sync_tables_datas.tablesyncdatas_size(); i++)
    {
        auto table = sync_tables_datas.tablesyncdatas(i).table();

        if (tables_datas_.find(table) == tables_datas_.end())
        {
            tables_datas_[table] = TableDatas();
        }

        TableDatas &table_datas = tables_datas_[table];
        table_datas.end_ = sync_tables_datas.tablesyncdatas(i).end();

        for (int j = 0; j < sync_tables_datas.tablesyncdatas(i).syncdatas_size(); j++)
        {
            Data data;
            data.start_ = sync_tables_datas.tablesyncdatas(i).syncdatas(j).start();
            data.end_ = sync_tables_datas.tablesyncdatas(i).syncdatas(j).end();
            data.is_successed_ = false;

            auto iter = std::find(table_datas.datas_.begin(), table_datas.datas_.end(), data);
            if (iter == table_datas.datas_.end())
            {
                table_datas.datas_.push_back(data);
            }
            else {
                iter->is_successed_ = false;
            }
        }

        saveFile(table.c_str(), table_datas);

        LOG(INFO) << table << "end = " << table_datas.end_ << " sync datas count = " << table_datas.datas_.size();
    }

}

void SyncDataCache::readFile(const char * file_name, TableDatas &table_datas)
{
    FILE *file = nullptr;
    fopen_s(&file, file_name, "rt");

    if (file == nullptr)
    {
        LOG(ERROR) << "Open file error";
        return;
    }

    char buf[256] = { 0 };

    if (fgets(buf, 256, file))
    {
        std::string temp = buf;

        StringReplace(temp, "/n", "");
        StringReplace(temp, "/r", "");
        StringReplace(temp, " ", "");

        table_datas.end_ = atoi(temp.c_str());
    }

    while (fgets(buf, 256, file) != nullptr)
    {
        std::string temp = buf;

        StringReplace(temp, "/n", "");
        StringReplace(temp, "/r", "");
        StringReplace(temp, " ", "");

        auto index = temp.find_first_of(",-");

        if (index != std::string::npos)
        {
            Data data;

            data.start_ = atoi(temp.substr(0, index).c_str());

            auto index1 = temp.find_last_of(",-");
            data.end_ = atoi(temp.substr(index + 1, index1 - index - 1).c_str());

            data.is_successed_ = atoi(temp.substr(index1 + 1, temp.length() - index1 - 1).c_str()) == 0 ? false : true;

            table_datas.datas_.push_back(data);
        }
        memset(buf, sizeof(buf), 0);
    };

    fclose(file);
}

void SyncDataCache::saveFile(const char * table, TableDatas &table_datas)
{
    std::string full_name = "./temp/";
    full_name += table;
    full_name += ".sync";

    FILE *file = nullptr;
    fopen_s(&file, full_name.c_str(), "wt");

    fprintf_s(file, "%d", table_datas.end_);

    for (auto iter = table_datas.datas_.begin(); iter != table_datas.datas_.end(); ++iter)
    {
        fprintf_s(file, "\n%d,%d,%d", iter->start_, iter->end_, iter->is_successed_ ? 1 : 0);
    }

    if (file == nullptr)
    {
        LOG(ERROR) << "Open file error";
        return;
    }

    fclose(file);
}
